<?php

namespace app\admin\model;

use think\facade\Db;

class AgentBalanceChangeApply
{
    private $error = '';
    private $table = 'agent_balance_change_apply';
    /**
     * 列表.
     */
    public function getList($params)
    {
        $where = [];
        $paginate = [
            'page' => $params['page'] ?? 1,
            'list_rows' => $params['list_rows'] ?? 10,
        ];
        $agentName = trim($params['agent_name'] ?? '');
        if ($agentName) {
            $agentIds = Db::name('agent')
                ->where('is_deleted', 0)
                ->where('username|company_name', 'like', '%' . $agentName . '%')
                ->column('id');
            if ($agentIds) {
                $where[] = ['agent_id', 'in', $agentIds];
            } else {
                $where[] = ['id', '=', 0];
            }
        }
        if (!empty($params['status'])) {
            $where[] = ['status', '=', $params['status']];
        }
        $auditTime = $params['audit_time'] ?? [];
        if (is_array($auditTime) && !empty($auditTime[0]) && $auditTime[1]) {
            $where[] = ['audit_time', 'between time', [strtotime($auditTime[0]), strtotime($auditTime[1] . ' 23:59:59')]];
        }
        $createdDate = $params['created_at'] ?? [];
        if (is_array($createdDate) && !empty($createdDate[0]) && $createdDate[1]) {
            $where[] = ['created_at', 'between time', [$createdDate[0], $createdDate[1] . ' 23:59:59']];
        }
        $list = Db::name($this->table)
            ->where($where)
            ->order('id desc')
            ->paginate($paginate)
            ->toArray();
        if ($list['total'] == 0) {
            return success('操作成功', $list);
        }

        $agentIds = array_unique(array_column($list['data'], 'agent_id'));
        $agent = Db::name('agent')
            ->whereIn('id', $agentIds)
            ->column('username, company_name', 'id');
        foreach ($list['data'] as $k => $v) {
            $list['data'][$k]['agent_name'] = $agent[$v['agent_id']]['username'] ?? '';
            $list['data'][$k]['company_name'] = $agent[$v['agent_id']]['company_name'] ?? '';
            if ($v['audit_time']) {
                $list['data'][$k]['audit_time'] = date('Y-m-d H:i:s', $v['audit_time']);
            } else {
                $list['data'][$k]['audit_time'] = '';
            }
        }

        return success('操作成功', $list);
    }

    /**
     * 加款申请审核
     */
    public function audit($params)
    {
        if (empty($params['id'])) {
            return fail('缺少参数 id');
        }
        if (empty($params['status'])) {
            return fail('缺少参数 status');
        }
        // 2审核通过 3审核不通过
        if (!in_array($params['status'], [2, 3])) {
            return fail('审核状态有误【' . $params['status'] . '】');
        }

        $info = Db::name($this->table)
            ->where('id', $params['id'])
            ->find();
        if (empty($info)) {
            return fail('充值申请不存在');
        }
        if ($info['status'] != 1) {
            return fail('该充值申请当前状态无法审核【' . $info['status'] . '】');
        }

        $tmpStatus = 24;
        $lock = Db::name($this->table)
            ->where('id', $info['id'])
            ->where('status', 1)
            ->update([
                'status' => $tmpStatus,
            ]);
        if (!$lock) {
            return fail('该充值申请当前状态无法审核' . __LINE__);
        }

        Db::startTrans();
        try {
            $res = Db::name($this->table)
                ->where('id', $params['id'])
                ->where('status', $tmpStatus)
                ->update([
                    'status' => $params['status'],
                    'audit_time' => time(),
                ]);
            if (!$res) {
                Db::rollback();
                return fail('审核失败，请联系管理员');
            }

            if ($params['status'] == 2) {
                // 审核通过
                $flag = $this->handleAccept($info);
            } else {
                // 审核不通过
                $flag = $this->handleReject($info);
            }
            if (false === $flag) {
                Db::rollback();
                return fail($this->error);
            }

            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();

            return fail('审核失败，请重试：' . $e->getMessage());
        }

        return success('审核成功');
    }

    /**
     * 处理审核通过
     */
    private function handleAccept($info)
    {
        if ($info['amount'] < 0) {
            // 减款的，扣冻结金额
            $absAmount = abs($info['amount']);
            $res = Db::name('agent')
                ->where('id', $info['agent_id'])
                ->where('freeze_amount', '>=', $absAmount)
                ->dec('freeze_amount', $absAmount)
                ->dec('recharge_amount', $absAmount)
                ->update();
            if (!$res) {
                $this->error = '冻结金额不足';
                return false;
            }
        } else {
            // 加款的，增加代理商余额
            $balance = Db::name('agent')
                ->where('id', $info['agent_id'])
                ->value('balance');
            Db::name('agent')
                ->where('id', $info['agent_id'])
                ->inc('balance', $info['amount'])
                ->inc('recharge_amount', $info['amount'])
                ->update([
                    'balance_last_updated_at' => date('Y-m-d H:i:s'),
                ]);
            Db::name('agent_balance_log')
                ->insert([
                    'agent_id' => $info['agent_id'],
                    'type' => BALANCE_CHANGE_APPLY,
                    'amount' => $info['amount'],
                    'old_balance' => $balance,
                    'new_balance' => $balance + $info['amount'],
                    'remark' => '通过加款申请：' . fen2yuan($info['amount']),
                    'quote_id' => $info['id'],
                ]);
        }

        return true;
    }

    /**
     * 处理审核不通过
     */
    private function handleReject($info)
    {
        if ($info['amount'] < 0) {
            $absAmount = abs($info['amount']);
            $balance = Db::name('agent')
                ->where('id', $info['agent_id'])
                ->value('balance');
            $res = Db::name('agent')
                ->where('id', $info['agent_id'])
                ->where('freeze_amount', '>=', $absAmount)
                ->inc('balance', $absAmount)
                ->dec('freeze_amount', $absAmount)
                ->update([
                    'balance_last_updated_at' => date('Y-m-d H:i:s'),
                ]);
            if (!$res) {
                $this->error = '冻结金额不足。' . $absAmount;
                return false;
            }
            Db::name('agent_balance_log')
                ->insert([
                    'agent_id' => $info['agent_id'],
                    'type' => BALANCE_CHANGE_APPLY,
                    'amount' => $absAmount,
                    'old_balance' => $balance,
                    'new_balance' => $balance + $absAmount,
                    'remark' => '拒绝加款申请：' . fen2yuan($absAmount),
                    'quote_id' => $info['id'],
                ]);
        }
        return true;
    }
}
